[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The current Amiga OS (V3.1) has a very limited stack handling compared to most other OSs: Every process has it’s own fixed sized stack - and that’s all about it. The usual default for this stack is 4k, but that’s not enough for more complicated purposes (like for example compilers). Setting a higher default is no real solution because it costs a lot of (widely unused) memory and may be overrun, too :-(.
But fortunately you can get stack extension with a little help of the compiler ;-).
1 Overview | and Desclaimer | |
2 How stack extension works | How it works (in detail). | |
5 How to use stack extension | Basic. | |
6 Stack extension fine tuning | Fine tuning. | |
7 Overhead of stack extension |
In this file you find everything necessary to use and understand stack extension. All parts of this document (as well as the stack extension code itself) are PD and therefore freely distributable. You use it at your own risk.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
For a reliable compiler supported stack extension mechanism you need to check the stack against overflow any time it grows by generating special checking code. This can happen at three different points in normal C code:
Functions may need lots of variables, fixed sized arrays, preserve registers etc. The space needed for this is collected together by the compiler and allocated at function entry. Therefore you may have to swap to a new stackframe. Note that the function’s arguments and local variables are accessed over the same mechanism - therefore it’s necessary to copy the arguments to the new stackframe. Since you cannot know how many arguments you have to copy (C allows for a variable number of arguments) a fixed (user configurable, See section Stack extension fine tuning.) amount of memory is copied.
Both allocate memory off the stack.
When calling library functions (glue code or link libraries) the arguments are put on the stack first, then the function gets called. Additionally a library function may use more or less stack on it’s own. The easiest way to handle this is to guarantee a minimum of free stack (user configurable, See section Stack extension fine tuning.).
The cleanup for the additional stack works equivalent.
3 Basic functions for stack extension | Basic functions for stack handling | |
4 Additional wrappers | Additional wrappers needed for performance |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These functions are only callable from assembly code. They are the core of the additional set.
‘___stkext’
Prepares a new stackframe with a minimum of d0 free bytes left. Returns on the new stackframe. Preserves all registers
‘___stkext_f’
Similar to the previous one, but this function copies the arguments of the caller and everything on top of them. d1 must be the offset (in bytes) of the caller’s returnaddress relative to sp. This returnaddress is replaced by a cleanup function’s address (no explicit cleanup necessary). Preserves all registers
‘___stkrst’
Similar to ’movel d0,sp’. Falls back to an old stackframe if necessary. Preserves all registers.
‘___stkovf’
Is the stack overflow handler (called if there is not enough memory to extend the stack further and the program has to be aborted). Does not return.
Additionally you find the current limit of the stack in
‘___stk_limit’
Note that this doesn’t point to the lower stack boundary but leaves some safety zone (See section Stack extension fine tuning.).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These functions are all optimized for speed by checking if the current stack is already large enough using it if possible and by not preserving ‘d0,d1,a0,a1’. Future versions of the compiler (implementing registerized parameters) might need a register preserving set. This is the reason why the basic interface (See section Basic functions for stack extension.) is documented.
Again all functions are only callable from assembly.
‘___link_a5_d0_f’
May be used at the top of a function instead of ‘link a5,d0’. Checks if the current stackframe is large enough and allocates a new one (over ‘___stkext_f’) if not.
‘___link_a5_0_f’
Same as above but treats ‘d0’ as 0.
‘___sub_d0_sp_f’
For usage at the top of a function, similar to ‘sub d0,sp’. Works over ‘___stkext_f’.
‘___sub_0_sp_f’
Same as above but treats ‘d0’ as 0.
‘___sub_d0_sp’
Works like ‘sub d0,sp’ but this time over ‘___stkext’.
‘___move_d0_sp’
‘___stkrst’ under a second name.
‘___unlk_a5_rts’
Use this function instead of a simple ‘unlk a5;rts’ if the current function calls ‘___sub_d0_sp’ and doesn’t clean up later (‘a5’ points to a different stackframe than ‘sp’). Works over ‘___stkrst’. Preserves ‘d0,d1’.
‘___stkchk_d0’
Just tests if there are ‘d0’ bytes space left on the stack - raising a stackoverflow if not.
‘___stkchk_0’
Tests if there is any space left.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
First of all you need a gcc capable of generating the right assembly output. You should find some source patches for gcc 2.6.3 in the same archive you got this file (you are reading) from. Use them to recompile your compiler.
Once you’ve got the new compiler you got two new target dependant switches:
You can mix functions compiled with or without these switches without problems. Note that this library builds on libnix and needs the ‘-noixemul’ switch.
Caution:
Do not use stack checking and/or extension switches when compiling hook or interrupt code. Both run in alien contexts with a different stack and all stack magic must fail. Also don’t try to do some other stack magic if you want to use stack extension.
Also note that a program compiled with stack extension/checking may ‘exit()’ at any function entry or when using alloca or variable sized arrays. Prepare your cleanup function accordingly (use ‘atexit()’).
If you like to write or call functions with more than 256 bytes of arguments (64 ints, longs or pointers) you should adjust the behaviour of the stack extension code (See section Stack extension fine tuning.).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To adjust the behaviour of the stack extension code to your personal needs you may set some of the following variables (or functions)
‘unsigned long __stk_minframe’ (default: 32768)
Minimum amount of memory to allocate for a new stackframe. Setting a higher value speeds the code up but costs more memory if it is unused.
‘unsigned long __stk_safezone’ (default: 2048)
Size of the safety zone (for ‘__stk_limit’). Set this to a higher value if you want to call functions with lots of arguments.
‘unsigned long __stk_argbytes’ (default: 256)
Number of bytes ‘__stkext_f()’ copies as arguments. Set this to a higher value if your functions may have lots of arguments.
‘void _CXOVF(void)’
Is a user replaceable stack overflow handler. The default one just pops up a requester, then exits. This function is not allowed to return.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The additional code needed for stack extension (or checking) costs memory and CPU power. Here are some numbers to give you a feeling for it (times in 1/60s, sizes in bytes (remember that there are lies, damned lies and benchmarks ;-) )):
Test normal checking extending extending (big stack) (big stack) (big stack) (small stack) Simple recursive function runtime 152 221 225 226 (function calling overhead) Variable sized 52 136 398 468 array runtime alloca runtime 31 118 118 118 Own code size 1040 1160 1140 Library code size 0 184 788
[Top] | [Contents] | [Index] | [ ? ] |
[Top] | [Contents] | [Index] | [ ? ] |
This document was generated on August 4, 2022 using texi2html 5.0.
The buttons in the navigation panels have the following meaning:
Button | Name | Go to | From 1.2.3 go to |
---|---|---|---|
[ << ] | FastBack | Beginning of this chapter or previous chapter | 1 |
[ < ] | Back | Previous section in reading order | 1.2.2 |
[ Up ] | Up | Up section | 1.2 |
[ > ] | Forward | Next section in reading order | 1.2.4 |
[ >> ] | FastForward | Next chapter | 2 |
[Top] | Top | Cover (top) of document | |
[Contents] | Contents | Table of contents | |
[Index] | Index | Index | |
[ ? ] | About | About (help) |
where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:
This document was generated on August 4, 2022 using texi2html 5.0.